{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The GraphConv model we created can now be applied used to search the set of commercially available compounds we just filtered.  \n",
    "Applying the model will consist of a few steps.\n",
    "1. Load the model from disc\n",
    "2. Create a featurizer\n",
    "3. Read an featurize the molecules that we will run through the model\n",
    "4. Examine the scores for the predictions\n",
    "5. Examine the chemical strucutres of the top predicted molecules\n",
    "6. Cluster the selected molecules\n",
    "7. Write the selected molecules from each cluster to a csv file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will begin by importing the necessary libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/sklearn/ensemble/weight_boosting.py:29: DeprecationWarning: numpy.core.umath_tests is an internal NumPy module and should not be imported. It will be removed in a future NumPy release.\n",
      "  from numpy.core.umath_tests import inner1d\n"
     ]
    }
   ],
   "source": [
    "import deepchem as dc\n",
    "import pandas as pd\n",
    "from rdkit.Chem import PandasTools, Draw\n",
    "from rdkit import DataStructs\n",
    "from rdkit.ML.Cluster import Butina\n",
    "from rdkit.Chem import rdMolDescriptors as rdmd\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We then read the model that we generated earlier from disc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/ops/math_grad.py:317: div (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Deprecated in favor of operator or tf.math.divide.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/ops/math_grad.py:317: div (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Deprecated in favor of operator or tf.math.divide.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n",
      "/home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/ops/gradients_impl.py:110: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.\n",
      "  \"Converting sparse IndexedSlices to a dense Tensor of unknown shape. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/training/saver.py:1266: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/tensorflow/python/training/saver.py:1266: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from model_dir/model-660\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from model_dir/model-660\n"
     ]
    }
   ],
   "source": [
    "model = dc.models.TensorGraph.load_from_dir(\"model_dir\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In order to generated predictions from our model, we first need to featurize the molecules we plan to use to generate predictions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "featurizer = dc.feat.ConvMolFeaturizer()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In order to featurize the molecules, we need to transform our SMILES file into a csv.  The DeepChem featurizer also requires an activity column, so we will add one then write the file to csv. **Is there another way to do this?**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"zinc.smi\",sep=\" \",header=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.columns=[\"SMILES\",\"Name\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "rows,cols = df.shape\n",
    "df[\"Val\"] = [0] * rows #just add add a dummy column to keep the featurizer happy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>SMILES</th>\n",
       "      <th>Name</th>\n",
       "      <th>Val</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CN1C(=O)C[C@H](N2CCN(C(=O)CN3CCCC3)CC2)C1=O</td>\n",
       "      <td>ZINC000000036436</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>CC(=O)NC[C@H](O)[C@H]1O[C@H]2OC(C)(C)O[C@H]2[C...</td>\n",
       "      <td>ZINC000000041101</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>C1CN(c2nc(-c3nn[nH]n3)nc(N3CCOCC3)n2)CCO1</td>\n",
       "      <td>ZINC000000054542</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>OCCN(CCO)c1nc(Cl)nc(N(CCO)CCO)n1</td>\n",
       "      <td>ZINC000000109481</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>COC(=O)c1ccc(S(=O)(=O)N(CCO)CCO)n1C</td>\n",
       "      <td>ZINC000000119782</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                              SMILES              Name  Val\n",
       "0        CN1C(=O)C[C@H](N2CCN(C(=O)CN3CCCC3)CC2)C1=O  ZINC000000036436    0\n",
       "1  CC(=O)NC[C@H](O)[C@H]1O[C@H]2OC(C)(C)O[C@H]2[C...  ZINC000000041101    0\n",
       "2          C1CN(c2nc(-c3nn[nH]n3)nc(N3CCOCC3)n2)CCO1  ZINC000000054542    0\n",
       "3                   OCCN(CCO)c1nc(Cl)nc(N(CCO)CCO)n1  ZINC000000109481    0\n",
       "4                COC(=O)c1ccc(S(=O)(=O)N(CCO)CCO)n1C  ZINC000000119782    0"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "infile_name = \"zinc_filtered.csv\"\n",
    "df.to_csv(infile_name,index=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can the read this csv file with a loader and featurize the molecules we plan to predict. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "loader = dc.data.CSVLoader(tasks=['Val'], smiles_field=\"SMILES\", featurizer=featurizer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading raw samples now.\n",
      "shard_size: 8192\n",
      "About to start loading CSV from zinc_filtered.csv\n",
      "Loading shard 1 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 0 took 21.497 s\n",
      "Loading shard 2 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 1 took 21.176 s\n",
      "Loading shard 3 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 2 took 21.333 s\n",
      "Loading shard 4 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 3 took 21.343 s\n",
      "Loading shard 5 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 4 took 21.213 s\n",
      "Loading shard 6 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 5 took 21.347 s\n",
      "Loading shard 7 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 6 took 21.283 s\n",
      "Loading shard 8 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "Featurizing sample 4000\n",
      "Featurizing sample 5000\n",
      "Featurizing sample 6000\n",
      "Featurizing sample 7000\n",
      "Featurizing sample 8000\n",
      "TIMING: featurizing shard 7 took 21.565 s\n",
      "Loading shard 9 of size 8192.\n",
      "Featurizing sample 0\n",
      "Featurizing sample 1000\n",
      "Featurizing sample 2000\n",
      "Featurizing sample 3000\n",
      "TIMING: featurizing shard 8 took 8.286 s\n",
      "TIMING: dataset construction took 205.402 s\n",
      "Loading dataset from disk.\n"
     ]
    }
   ],
   "source": [
    "dataset = loader.featurize(infile_name, shard_size=8192)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The featurized molecules can be used to generate predcitions with the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "pred = model.predict(dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "pred_df = pd.DataFrame([x.flatten() for x in pred],columns=[\"Neg\",\"Pos\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A distribtion plot provides a nice overview of the distribution of scores.  We cna see that only a few molecules have scores >= 0.3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/ubuntu/anaconda3/envs/deepchem/lib/python3.6/site-packages/scipy/stats/stats.py:1713: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.\n",
      "  return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f04e77e0978>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAEGCAYAAAB8Ys7jAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAX2klEQVR4nO3dfaxk9X3f8fd35u4uTzZesgvC2M6aFPKguI7NusYhttJskG1cFSrZwkrjINcSSR9ch1Zq1q5U6kaWiRrVoUrrgLAbqjxaxC60pDRoU2rHwdsshhjMNiyFlqctLMZgHnd3Zr79Y86ZO3fu3N3x7p1798fv/ZLQvTNz5sz3N3P92Z+/8zvnRGYiSSpPZ70LkCQdGwNckgplgEtSoQxwSSqUAS5JhVpYyxfbsmVLbtu2bS1fUpKKd9dddz2dmVsn71/TAN+2bRt79uxZy5eUpOJFxP+ddr8tFEkqlAEuSYUywCWpUAa4JBXKAJekQhngklQoA1ySCmWAS1Khigvwr9z9GO+/9mvrXYYkrbviAnzfky+wd//3GAy8EIWkuhUX4P3mCkJ9ryQkqXLlBXi/CXBn4JIqV1yA95rgPtwfrHMlkrS+igvwdubtDFxS7YoL8HYG3jPAJVWuuADvDwbNTwNcUt2KC3B74JI0VFyAD+yBSxJQYIDbA5ekoeIC3FUokjRUXIDbA5ekoeIC3Bm4JA0VF+D2wCVpqLgAdxWKJA0VF+C95kAee+CSaldcgNsDl6Sh4gLcHrgkDRUX4KMZeN8Al1S34gK8129n4PbAJdWtuAAfpC0USYICA7znl5iSBBQY4G1w9+yBS6rcTAEeEVdFxLcj4r6I+P2IOCkizoiI2yNiX/Nz87yLhcXetz1wSbU7aoBHxDnAPwa2Z+aPA13gw8BOYFdmngfsam7PXb9vD1ySYPYWygJwckQsAKcATwCXAjc2j98IXLb65S1nD1ySho4a4Jn5OPDrwCPAfuC5zPwT4KzM3N9ssx84c9rzI+LKiNgTEXsOHDhw3AXbA5ekoVlaKJsZzrbfDLweODUifn7WF8jM6zNze2Zu37p167FX2uinM3BJgtlaKD8LPJyZBzLzMPBl4CeBJyPibIDm51PzK3NR2wM/7JeYkio3S4A/AlwYEadERAA7gL3ALcAVzTZXADfPp8Sleh5KL0nA8MvJI8rM3RFxE/BNoAfcDVwPnAZ8KSI+xjDkPzTPQlt9T2YlScAMAQ6QmVcDV0/cfZDhbHxNteu/7YFLql1RR2JmJm1u2wOXVLuiAnx81m0PXFLtigrw8b63PXBJtSsqwJfMwA1wSZUrKsCXzsDtgUuqW1EBPj7r9lB6SbUrKsDHZ922UCTVrqgAH++a+CWmpNoVFeDjM3B74JJqV1SA2wOXpEVFBXjPZYSSNFJUgPc9kEeSRooK8PG2iT1wSbUrKsAHaQ9cklpFBbg9cElaVFSA95u2SYQ9cEkqKsDbtsmmhY4zcEnVKyrA29DetNDlcN8vMSXVragA7w2cgUtSq6gAH83ANxjgklRkgJ+00PVLTEnVKyrA29DeuNChZw9cUuWKCvD+WA/cGbik2hUV4O3h85sWuvbAJVWvqAAf9cA3OAOXpKICvDe2DtweuKTaFRXgg7FlhM7AJdWuqAD3QB5JWlRUgI8fSt8bJJmGuKR6FRXg4zNw8JSykupWVIC3p5PdtGFYtn1wSTUrKsDHV6GAM3BJdSsqwAcTLRRn4JJqVlSAT/bAXQsuqWZFBXh/kETABr/ElKSyArw3SBY6wUInRrclqVYzBXhEvC4iboqI/xUReyPiXRFxRkTcHhH7mp+b511sf5B0O0G34wxckmadgV8L3JaZPwK8FdgL7AR2ZeZ5wK7m9lz1+slCp8OG7nAG7nUxJdXsqAEeEa8F3gN8ASAzD2Xms8ClwI3NZjcCl82ryFZ/MGhm4NHcdgYuqV6zzMDPBQ4A/yEi7o6IGyLiVOCszNwP0Pw8c9qTI+LKiNgTEXsOHDhwXMX20x64JLVmCfAF4O3A5zPzbcCLfB/tksy8PjO3Z+b2rVu3HmOZQ/1B0rEHLknAbAH+GPBYZu5ubt/EMNCfjIizAZqfT82nxEXDHniw0HUGLklHDfDM/H/AoxHxw81dO4D7gVuAK5r7rgBunkuFY9pVKKMWil9iSqrYwozbfRz43YjYCDwEfJRh+H8pIj4GPAJ8aD4lLmrXgXftgUvSbAGemfcA26c8tGN1yzmyxRm4PXBJKupIzP5guA7cGbgkFRbgvWYG3h7IYw9cUs2KCvDJA3mcgUuqWVEB3rMHLkkjRQV431UokjRSVIDbA5ekRUUF+GCQLHSdgUsSFBbgwxl4xx64JFFYgPcHSTdwBi5JFBbg7QzcHrgkFRbg/cFgySoUWyiSalZUgPcGSbe7uA7cFoqkmhUV4IOJdeDOwCXVrKgA702cD9yLGkuqWVEB3h6J2ekEnXAGLqluRQV4OwMHWOh07IFLqlpRAd4fC/BuJ5yBS6paUQHe6w9GK1AWOmEPXFLVZr0m5glhfAbez2Tv/u/xe7sfWbLNz73zTetRmiStuaJm4P3M0QqUTgQDJ+CSKlZWgI/NwDsBg7QHLqleRQX4+CqUTicMcElVKybAB4Mkc/FMhN1wFYqkuhUT4O2a7yU9cPNbUsWKCfB2tt1tlhF2OvbAJdWtnADPKTNwp+CSKlZOgPfbGfjYkZjOwCVVrJgA7zWLvhe69sAlCQoK8LYH3omxdeAmuKSKFRPg01ehGOCS6lVMgC+uQlk8kMd14JJqVlyAtz3wrj1wSZUrJsB7k+vAPReKpMoVE+D9yR6450KRVLliArxdRri4CiXweg6SalZMgE/OwLvOwCVVbuYAj4huRNwdEf+luX1GRNweEfuan5vnV+ZYD7zr+cAlCb6/GfgngL1jt3cCuzLzPGBXc3tulvXAPReKpMrNFOAR8QbgA8ANY3dfCtzY/H4jcNnqlrbUsnXgEfTNb0kVm3UG/hvAPwPGvzY8KzP3AzQ/z5z2xIi4MiL2RMSeAwcOHHOhizPw9nSyzsAl1e2oAR4Rfwt4KjPvOpYXyMzrM3N7Zm7funXrsewCGF8HPrzdtQcuqXILM2xzEfC3I+IS4CTgtRHxO8CTEXF2Zu6PiLOBp+ZZaL9ZRrh4II+rUCTV7agz8Mz8ZGa+ITO3AR8G/jQzfx64Bbii2ewK4Oa5VQn0+tMO5JnnK0rSie141oFfA1wcEfuAi5vbczPtS0x74JJqNksLZSQz7wDuaH7/DrBj9Uuabtkl1TqQDPvg7dGZklST4o7EHF1SrQlt++CSalVMgC/2wBe/xAQYeD4USZUqJsBHl1RrKm4m4s7AJVWrmADvTTmQB7wupqR6FRPgi+vAF1ehwOKXm5JUm4ICfOJ0sqMvMdetJElaV8UE+LLTyTaV20KRVKtiAnza6WTBLzEl1auYAG9n4KNLqnXsgUuqWzEBvvIMfN1KkqR1VUyA95YdiTm83x64pFoVE+D9wYBuJ4iJFoo9cEm1KijAF2ffMH4ovQEuqU4FBfhg1P+G8QN51qsiSVpfxQR4b5BLZ+DtOnBbKJIqVUyA9ycCvGsLRVLlignw3iCntlCcgUuqVTEB3u9PtlBcBy6pbuUEeOboVLKweD7wvgkuqVLlBPjkl5i2UCRVrpgAn+yBdz2QR1Llignw/mAw6nuD18SUpGICvNefXIUy/OkMXFKtignwZT1wTycrqXLlBHhO9MA9kEdS5coJ8BVXoaxXRZK0vooJ8GEPfGwduOdCkVS5YgJ8pRm4B/JIqlUxAd5rLujQch24pNoVE+CTM/D2NyfgkmpVToBPrEKJCDrhKhRJ9SomwHsTZyOEYR/cdeCSalVMgPcHyUJ3IsA74QxcUrWKCvBuZ2m53Qh74JKqVUyA9wbJxAR82AO3hSKpUsUE+LQZeKcTrgOXVK2jBnhEvDEi/ntE7I2Ib0fEJ5r7z4iI2yNiX/Nz8zwL7Q0GS1ahwPBLTPNbUq1mmYH3gH+amT8KXAj8w4j4MWAnsCszzwN2Nbfnpj+A7kQPpdsJWyiSqnXUAM/M/Zn5zeb354G9wDnApcCNzWY3ApfNq0gYXtBh+QzcHriken1fPfCI2Aa8DdgNnJWZ+2EY8sCZq13cuN5ghXXg9lAkVWrmAI+I04A/An45M7/3fTzvyojYExF7Dhw4cCw1As2XmGEPXJJaMwV4RGxgGN6/m5lfbu5+MiLObh4/G3hq2nMz8/rM3J6Z27du3XrMhfYGOb0HboJLqtQsq1AC+AKwNzP/zdhDtwBXNL9fAdy8+uUt6k9clR7sgUuq28IM21wEfAS4NyLuae77FHAN8KWI+BjwCPCh+ZQImTl9HbjnQpFUsaMGeGb+GYtnb520Y3XLma7tkiybgXeCwWAtKpCkE08RR2L2mpSeXIUyPBeKM3BJdSoiwNulgstn4PbAJdWriADvNQE+bR24AS6pVkUEeL9/hAC3By6pUmUEeK7QQglchSKpWmUE+KiFsvx0sh7II6lWRQR4b4UvMV2FIqlmRQT4EXvg5rekShUR4CutA+90sIUiqVpFBHj/CMsI/RJTUq2KCPCVeuAdr8gjqWJFBPhKM/Cu68AlVayoAF/oejpZSWoVEeC9I60DN8AlVaqIAF/xZFbNMsI0xCVVqIgAb5cRdqZcExNwLbikKhUR4Cv1wNubtlEk1aioAF9+IE8zA3cKLqlCRQX4ZA98Q3dY/sGeawkl1aeIAF/pgg5nnLoRgKdfPLjmNUnSeisiwBdn4EvL3fqaTQA8/fyhNa9JktZbEQG+OANfev/pJ29gQzc48Pwr61CVJK2vIgK8Pzob4cSBPBFsOW0TT7/gDFxSfQoJ8OHPyS8xAbactokDL9gDl1SfQgJ8+vnAYdgH/+6LhzjcdyWKpLoUEeArnU4WYOtpm0jgOy/aRpFUlyICfKUDeQC2NCtRDjxvG0VSXYoI8F5/+jJCgC2nNWvB7YNLqkwRAd7OwKfkN5sWupx+8gZn4JKqs7DeBcyive7l+Az8U1+5d8k29zz6LPc8+uyy+2cxvDDE0beBlbfb2A0O9ZNOwNmnn8QHL3gj1+7axzmvO4nHn31l9Hi7r4//zHl8/o4HedubNrP74Wd4zaYuzx/sj352At6x7Qwe++5L7H/uFQYJr9nU5d5Pv4+LrtnF48++Qifgoc9+gLdcfdvoue3jsNhWeuAzl3DRNbt4w+ZTuPDcHwAYvfYf/uK7ALj8ujsBuP+J57j30+/j3E/eumTfn9hxHlddfD7nfvJW3rHtjNHzWm+5+jb+3k+dy1UXn8/l193JH/7iu/jc7Q8A8I2HvrNk+/b+qy4+n207bx3t+6JrdvHBC964ZPvLr7tzVPNVF5+/7PmXX3cnux9+hne++Qzuf+I5AO799PuO+Fl+7vYHuOri8/nc7Q/wxT97iNeevIGv79yx5PFrd+3j/1zzgWXPabVjnLbvtv7Jbdr3ePK9aMfx2Hdf4us7d3DRNbv4+s4dS8b5lqtvG41rfL+T+xx/zpGsVP+092ly+/az/vwdD/LAZy454j7ecvVtHOwNeOAzl4z2145v8nXa2tv3fvI9n2bbzltHf/eTzv/nf3zU+lYab3v7prseXVIrsKz+lfYFR/8cjldRM/BpPfDVMMu5sAZ55O3acB4kPP7sK1y7ax8w/H388Xaba3ft41A/2f3wMwA8f7C/5OcgYffDz/D4s6+MXrd9rN3n5P3jjz/+7Csc6ufodR9/9hV2P/wM1+7at+y1Yfhaux9+Zsnrj++zHU9b16TnD/ZH27SPt681uX17//jttsbJ7cdrnvb8dtu29rbeI2mfe+2ufTx/sD96PycfP9J9096DdrvxmiafM+29aB9r62h/jo9zfFzTPrfx/U2rf9JK9U+rbXL79rMe/5teyfMH+6PtJv83Mfk6K/1dzPIa08xS37Q6xm9P1grL619pX7PWfzyKCPDFHvh8AlySSlREgPcHAyIWTx8rSSokwHuDdPYtSROKCPD+IJddTk2SaldEgDsDl6Tligjw/iDntgJFkkp1XAEeEe+LiL+KiAcjYudqFTWpP0gWJk8GLkmVO+YDeSKiC/w74GLgMeAvIuKWzLx/tYprXfa213PBD25e7d0WKdMLOEsaimMNhIh4F/AvM/O9ze1PAmTmZ1d6zvbt23PPnj3H9HqTtu28dVX2U7oIGP8Iu50YHfjU2tANDq9wUMNJGzpkLr0wdLuPyX2N39600KETQZJLnr9pocPB3oCTNnR45fBgyesEw+3b+zd2OxxqTgO8caHDod7S7YEl+zh5Q3fJ81caV1tbBLSNt3arTHj5cH9UZ2vjQodO816292/sdob7iGEdJ2/ojrZ/+XCfUzYu3h7fd1v/tOe04xi/b7yW9n0Yf//a38ffk/b9nNzn+O32e//x96D9W3n5cH/FbVovHeov2e+mhQ4Jyz6naJ7d7iuTZX8X7Wc9Pr72eS8f7i/7/Nvt2xrH6xtkMsjhZKb9/Nv3Zlz7/o+vf5g2zvHxnrKxO6p//P0PFnfSvnfjY562L2DJ38h1H7mAd5+3dfoTjiIi7srM7ZP3H8+h9OcAj47dfgx455QXvhK4srn5QkT81XG85rgtwNOrtK8TXU1jBcf7alfleN/zq8e1jx+cdufxBPi0f3uW/cOWmdcD1x/H60x/8Yg90/5FejWqaazgeF/tHO/qOZ5vBh8D3jh2+w3AE8dXjiRpVscT4H8BnBcRb46IjcCHgVtWpyxJ0tEccwslM3sR8Y+A/wZ0gS9m5rdXrbKjW/W2zAmsprGC4321c7yr5JhXoUiS1pdHx0hSoQxwSSrUCR3gRztUP4b+bfP4tyLi7etR52qZYbx/txnntyLizyPiretR52qZ9VQMEfGOiOhHxAfXsr7VNst4I+KnI+KeiPh2RPyPta5xtczwt3x6RPzniPjLZqwfXY86V0tEfDEinoqI+1Z4fD5ZlZkn5H8Mvxj938C5wEbgL4Efm9jmEuC/MlyTfiGwe73rnvN4fxLY3Pz+/lf7eMe2+1Pgj4EPrnfdc/58XwfcD7ypuX3metc9x7F+Cvi15vetwDPAxvWu/TjG/B7g7cB9Kzw+l6w6kWfgfwN4MDMfysxDwB8Al05scynwH3PoG8DrIuLstS50lRx1vJn555n53ebmNxiuvS/VLJ8vwMeBPwKeWsvi5mCW8f4c8OXMfAQgM0sd8yxjTeA1ERHAaQwDvLe2Za6ezPwqwzGsZC5ZdSIH+LRD9c85hm1K8f2O5WMM/0Uv1VHHGxHnAH8H+K01rGteZvl8zwc2R8QdEXFXRPzCmlW3umYZ628CP8rw4L97gU9k5oBXr7lk1fEcSj9vsxyqP9Ph/IWYeSwR8TcZBvhPzbWi+ZplvL8B/Epm9qP8KzLNMt4F4AJgB3AycGdEfCMzH5h3catslrG+F7gH+Bngh4DbI+Jrmfm9eRe3TuaSVSdygM9yqP6r6XD+mcYSEX8duAF4f2Z+Z41qm4dZxrsd+IMmvLcAl0RELzP/09qUuKpm/Xt+OjNfBF6MiK8CbwVKC/BZxvpR4JocNogfjIiHgR8B/ufalLjm5pJVJ3ILZZZD9W8BfqH5hvdC4LnM3L/Wha6So443It4EfBn4SIGzsklHHW9mvjkzt2XmNuAm4B8UGt4w29/zzcC7I2IhIk5heHbPvWtc52qYZayPMPx/GkTEWcAPAw+taZVray5ZdcLOwHOFQ/Uj4peax3+L4cqES4AHgZcY/qtepBnH+y+AHwD+fTMr7WWhZ3WbcbyvGrOMNzP3RsRtwLeAAXBDZk5dlnYim/Gz/VXgtyPiXobthV/JzGJPMRsRvw/8NLAlIh4DrgY2wHyzykPpJalQJ3ILRZJ0BAa4JBXKAJekQhngklQoA1ySCnXCLiOUVltE9Bketr3AcH31FZn50vpWJR07Z+CqycuZ+ROZ+ePAIeCX1rsg6XgY4KrV14C/BhAR/yQi7mv+++XmvlMj4tbmfNX3RcTl61qtNIUtFFUnIhYYnk/9toi4gOFRce9keETg7uZCCucCT2TmB5rnnL5e9UorcQaumpwcEfcAexiei+MLDM/o+JXMfDEzX2B4rpl3M+yV/2xE/FpEvDszn1u3qqUVOANXTV7OzJ8YvyNWOE9tZj7QzM4vAT4bEX+Smf9qLYqUZuUMXLX7KnBZRJwSEacyvIDE1yLi9cBLmfk7wK8zvFyWdEJxBq6qZeY3I+K3WTwP9Q2ZeXdEvBf41xExAA4Df3+9apRW4tkIJalQtlAkqVAGuCQVygCXpEIZ4JJUKANckgplgEtSoQxwSSrU/we5ZaLBdZ7WhQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.distplot(pred_df.Pos,rug=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The dataframe with the scores can be joined to the dataframe with the SMILES.  This will give us the ability to view the top scoring molecules."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "combo_df = df.join(pred_df,how=\"outer\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "combo_df.sort_values(\"Pos\",inplace=True,ascending=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Adding a molecule column to the dataframe enables us to look at the chemical strucutres of the hits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "PandasTools.AddMoleculeColumnToFrame(combo_df,\"SMILES\",\"Mol\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>SMILES</th>\n",
       "      <th>Name</th>\n",
       "      <th>Val</th>\n",
       "      <th>Neg</th>\n",
       "      <th>Pos</th>\n",
       "      <th>Mol</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>55110</th>\n",
       "      <td>Cn1cncc1C(=O)NC[C@@H](CO)NC(=O)c1cncn1C</td>\n",
       "      <td>ZINC000644062250</td>\n",
       "      <td>0</td>\n",
       "      <td>0.004964</td>\n",
       "      <td>0.995036</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>63517</th>\n",
       "      <td>O=C(NC[C@@H](CO)NC(=O)c1cnccn1)c1cnccn1</td>\n",
       "      <td>ZINC000680525179</td>\n",
       "      <td>0</td>\n",
       "      <td>0.008454</td>\n",
       "      <td>0.991546</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12672</th>\n",
       "      <td>Cn1nnc2cc(C(=O)N[C@@H](CO)CN3CCOCC3)cnc21</td>\n",
       "      <td>ZINC000339212693</td>\n",
       "      <td>0</td>\n",
       "      <td>0.038073</td>\n",
       "      <td>0.961927</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12673</th>\n",
       "      <td>Cn1nnc2cc(C(=O)N[C@H](CO)CN3CCOCC3)cnc21</td>\n",
       "      <td>ZINC000339212694</td>\n",
       "      <td>0</td>\n",
       "      <td>0.038073</td>\n",
       "      <td>0.961927</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21122</th>\n",
       "      <td>O=C(NCCNc1ccc(C(=O)NCCO)nn1)c1cc[nH]n1</td>\n",
       "      <td>ZINC000355577849</td>\n",
       "      <td>0</td>\n",
       "      <td>0.038931</td>\n",
       "      <td>0.961069</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                          SMILES              Name  Val  \\\n",
       "55110    Cn1cncc1C(=O)NC[C@@H](CO)NC(=O)c1cncn1C  ZINC000644062250    0   \n",
       "63517    O=C(NC[C@@H](CO)NC(=O)c1cnccn1)c1cnccn1  ZINC000680525179    0   \n",
       "12672  Cn1nnc2cc(C(=O)N[C@@H](CO)CN3CCOCC3)cnc21  ZINC000339212693    0   \n",
       "12673   Cn1nnc2cc(C(=O)N[C@H](CO)CN3CCOCC3)cnc21  ZINC000339212694    0   \n",
       "21122     O=C(NCCNc1ccc(C(=O)NCCO)nn1)c1cc[nH]n1  ZINC000355577849    0   \n",
       "\n",
       "            Neg       Pos                                                Mol  \n",
       "55110  0.004964  0.995036  <img src=\"...  \n",
       "63517  0.008454  0.991546  <img src=\"...  \n",
       "12672  0.038073  0.961927  <img src=\"...  \n",
       "12673  0.038073  0.961927  <img src=\"...  \n",
       "21122  0.038931  0.961069  <img src=\"...  "
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "combo_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Based on what we see above, it looks like many of the hits are similar.  Let's look at a few more molecules. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=1000x400 at 0x7F04E7D0A1D0>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Draw.MolsToGridImage(combo_df.Mol[:10],molsPerRow=5,legends=[\"%.2f\" % x for x in combo_df.Pos[:10]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Indeed many of the molecules are very similar and might end up being redundant in our screen.  One way of being more efficient with our screen would be to cluster the molecules and only screen the highest scoring molecule in each cluster. The RDKit has an implementation of the Butina clustering method, one of the most highly used methods in Cheminformatics. A small amount of code is necessary to cluster a set of molecules.  The only parameter required for Butina clustering is the cluster cutoff.  If the Tanimoto similarity of two molecules is greater than the cutoff, the molecules are put into the same cluster.  If the similarity is less than the cutoff the molecules are put into different clusters. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "def butina_cluster(mol_list,cutoff=0.35):\n",
    "    fp_list = [rdmd.GetMorganFingerprintAsBitVect(m, 3, nBits=2048) for m in mol_list]\n",
    "    dists = []\n",
    "    nfps = len(fp_list)\n",
    "    for i in range(1,nfps):\n",
    "        sims = DataStructs.BulkTanimotoSimilarity(fp_list[i],fp_list[:i])\n",
    "        dists.extend([1-x for x in sims])\n",
    "    mol_clusters = Butina.ClusterData(dists,nfps,cutoff,isDistData=True)\n",
    "    cluster_id_list = [0]*nfps\n",
    "    for idx,cluster in enumerate(mol_clusters,1):\n",
    "        for member in cluster:\n",
    "            cluster_id_list[member] = idx\n",
    "    return cluster_id_list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before clustering, we will create a new dataframe with only the top 100 scoring molecules. Since combo_df is already sorted, we only have to use the \"head\" function to select the first 100 rows in the dataframe. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "best_100_df = combo_df.head(100).copy()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then create a new column containing the cluster identifier for each compound."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "best_100_df[\"Cluster\"] = butina_cluster(best_100_df.Mol)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>SMILES</th>\n",
       "      <th>Name</th>\n",
       "      <th>Val</th>\n",
       "      <th>Neg</th>\n",
       "      <th>Pos</th>\n",
       "      <th>Mol</th>\n",
       "      <th>Cluster</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>55110</th>\n",
       "      <td>Cn1cncc1C(=O)NC[C@@H](CO)NC(=O)c1cncn1C</td>\n",
       "      <td>ZINC000644062250</td>\n",
       "      <td>0</td>\n",
       "      <td>0.004964</td>\n",
       "      <td>0.995036</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "      <td>49</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>63517</th>\n",
       "      <td>O=C(NC[C@@H](CO)NC(=O)c1cnccn1)c1cnccn1</td>\n",
       "      <td>ZINC000680525179</td>\n",
       "      <td>0</td>\n",
       "      <td>0.008454</td>\n",
       "      <td>0.991546</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "      <td>48</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12672</th>\n",
       "      <td>Cn1nnc2cc(C(=O)N[C@@H](CO)CN3CCOCC3)cnc21</td>\n",
       "      <td>ZINC000339212693</td>\n",
       "      <td>0</td>\n",
       "      <td>0.038073</td>\n",
       "      <td>0.961927</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "      <td>27</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12673</th>\n",
       "      <td>Cn1nnc2cc(C(=O)N[C@H](CO)CN3CCOCC3)cnc21</td>\n",
       "      <td>ZINC000339212694</td>\n",
       "      <td>0</td>\n",
       "      <td>0.038073</td>\n",
       "      <td>0.961927</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "      <td>27</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21122</th>\n",
       "      <td>O=C(NCCNc1ccc(C(=O)NCCO)nn1)c1cc[nH]n1</td>\n",
       "      <td>ZINC000355577849</td>\n",
       "      <td>0</td>\n",
       "      <td>0.038931</td>\n",
       "      <td>0.961069</td>\n",
       "      <td><img src=\"\" alt=\"Mol\"/></td>\n",
       "      <td>47</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                          SMILES              Name  Val  \\\n",
       "55110    Cn1cncc1C(=O)NC[C@@H](CO)NC(=O)c1cncn1C  ZINC000644062250    0   \n",
       "63517    O=C(NC[C@@H](CO)NC(=O)c1cnccn1)c1cnccn1  ZINC000680525179    0   \n",
       "12672  Cn1nnc2cc(C(=O)N[C@@H](CO)CN3CCOCC3)cnc21  ZINC000339212693    0   \n",
       "12673   Cn1nnc2cc(C(=O)N[C@H](CO)CN3CCOCC3)cnc21  ZINC000339212694    0   \n",
       "21122     O=C(NCCNc1ccc(C(=O)NCCO)nn1)c1cc[nH]n1  ZINC000355577849    0   \n",
       "\n",
       "            Neg       Pos                                                Mol  \\\n",
       "55110  0.004964  0.995036  <img src=\"...   \n",
       "63517  0.008454  0.991546  <img src=\"...   \n",
       "12672  0.038073  0.961927  <img src=\"...   \n",
       "12673  0.038073  0.961927  <img src=\"...   \n",
       "21122  0.038931  0.961069  <img src=\"...   \n",
       "\n",
       "       Cluster  \n",
       "55110       49  \n",
       "63517       48  \n",
       "12672       27  \n",
       "12673       27  \n",
       "21122       47  "
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "best_100_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can use the \"unique\" function to determine how many unique clusters we have. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "49"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(best_100_df.Cluster.unique())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ultimately, we would like to purchase these compounds.  In order to do this, we need need to save a csv file with molecules we plan to purchase.  The \"drop_duplicates\" function can be used to select one molecule per cluster.  By default, the function starts from the top of the table and removes rows with values that have already been seen. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "best_cluster_rep_df = best_100_df.drop_duplicates(\"Cluster\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(49, 7)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "best_cluster_rep_df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "best_cluster_rep_df.to_csv(\"best_cluster_represenatives.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
